package net.jiastudy.biz.targettask.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import net.jiastudy.biz.assessment.entity.Assessment;
import net.jiastudy.biz.assessment.entity.AssessmentDetail;
import net.jiastudy.biz.assessment.service.AssessmentService;
import net.jiastudy.biz.datasync.TaskImporter;
import net.jiastudy.biz.enums.AuditStatus;
import net.jiastudy.biz.enums.DeptType;
import net.jiastudy.biz.enums.TargetTaskLevel;
import net.jiastudy.biz.sys.entity.Dept;
import net.jiastudy.biz.sys.entity.File;
import net.jiastudy.biz.sys.entity.FileTarget;
import net.jiastudy.biz.sys.service.AttachmentService;
import net.jiastudy.biz.sys.service.DeptService;
import net.jiastudy.biz.targettask.entity.*;
import net.jiastudy.biz.targettask.mapper.TargetTaskMapper;
import net.jiastudy.biz.targettask.mapper.TaskYearMapper;
import net.jiastudy.biz.targettask.service.TargetTaskService;
import net.jiastudy.biz.targettask.service.TargetWorkService;
import net.jiastudy.biz.user.entity.User;
import net.jiastudy.core.base.BaseService;
import net.jiastudy.core.exception.ServiceException;
import net.jiastudy.core.utils.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
@Transactional(rollbackFor = Exception.class)
public class TargetTaskServiceImpl extends BaseService<TargetTaskMapper, TargetTask> implements TargetTaskService {
    @Resource
    private TaskYearMapper taskYearMapper;

    @Resource
    private TargetWorkService targetWorkService;

    @Resource
    private AssessmentService assessmentService;

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private DeptService deptService;

    @Override
    public TaskYear createTaskYear(TaskYear taskYear) {
        TaskYear dbTaskYear = getTaskYearByCode(taskYear.getCode());
        if (null != dbTaskYear) {
            throw new ServiceException("该code的年度已经存在");
        }
        taskYearMapper.insert(taskYear);

        return taskYear;
    }

    @Override
    public Boolean deleteTask(Long taskId) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("parent_id", taskId);

        if (this.selectCount(wrapper) > 0) {
            throw new ServiceException("该任务下面还有子任务，请先删除子任务");
        }

        this.deleteById(taskId);

        targetWorkService.deleteWorksByTaskId(taskId);

        return true;
    }

    @Override
    public TaskYear updateTaskYear(TaskYear taskYear) {
        TaskYear dbTaskYear = taskYearMapper.selectById(taskYear.getId());
        if (null == dbTaskYear) {
            throw new ServiceException("该年度不存在");
        }

        if (!dbTaskYear.getCode().equals(taskYear.getCode()) && null != getTaskYearByCode(taskYear.getCode())) {
            throw new ServiceException("该code的年度已经存在");
        }

        taskYearMapper.updateById(taskYear);

        return taskYear;
    }

    @Override
    public boolean deleteTaskYear(Long id) {
        taskYearMapper.deleteById(id);

        return true;
    }

    @Override
    public Page<TaskYear> searchTaskYears(Page<TaskYear> page, Map<String, String> conditions, Sort sort) {
        Wrapper<TaskYear> wrapper = new EntityWrapper<>();
        this.generateSort(wrapper, sort);
        if (conditions.containsKey("code") && StrUtil.isNotEmpty(conditions.get("code"))) {
            wrapper.like("code", conditions.get("code"));
        }

        if (conditions.containsKey("title") && StrUtil.isNotEmpty(conditions.get("title"))) {
            wrapper.like("title", conditions.get("title"));
        }

        List<TaskYear> taskYears = taskYearMapper.selectPage(page, wrapper);

        page.setRecords(taskYears);

        return page;
    }

    @Override
    public List<TaskYear> findAllTaskYears() {
        Wrapper<TaskYear> wrapper = new EntityWrapper<>();
        wrapper.orderBy("code", false);

        return taskYearMapper.selectList(wrapper);
    }

    private boolean checkFirstNodeNeedAudit(TargetTask targetTask) {
        if(targetTask.getLevel() == TargetTaskLevel.top && targetTask.getAssess()) {
            return true;
        }
        if(targetTask.getLevel() == TargetTaskLevel.top && !targetTask.getAssess()) {
            return false;
        } else {
            TargetTask parentTargetTask = this.selectById(targetTask.getParentId());
            return checkFirstNodeNeedAudit(parentTargetTask);
        }
    }

    @Override
    public List<Dept> findAssessmentDeptsByAssessmentedDeptIdAndYearId(Long deptId, Long yearId) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("receive_dept_id", deptId);
        wrapper.eq("year", yearId);
        List<TargetTask> targetTasks = this.selectList(wrapper);
        if (targetTasks.isEmpty()) {
            return null;
        }

        List<TargetTask> newTargetTasks = new ArrayList<>();
        for (TargetTask targetTask: targetTasks) {
            //寻找父级任务是否需要考核
            if (checkFirstNodeNeedAudit(targetTask)) {
                newTargetTasks.add(targetTask);
            }
        }

        if (newTargetTasks.isEmpty()) {
            return null;
        }

        Set<Long> assessmentDeptIds = BeanUtils.getFiled(newTargetTasks, "originatedDeptId", long.class);

        if (null == assessmentDeptIds) {
            return null;
        }

        List<Assessment> assessments = assessmentService.findAssessmentByYearAndAssessmentedDeptId(yearId, deptId);
        if (assessments != null && !assessments.isEmpty()) {
            Set<Long> dbAssessmentDeptIds = BeanUtils.getFiled(assessments, "assessmentDeptId", long.class);
            for (Long item : dbAssessmentDeptIds) {
                if (assessmentDeptIds.contains(item)) {
                    assessmentDeptIds.remove(item);
                }
            }
        }
        if (assessmentDeptIds.isEmpty()) {
            return null;
        }

        return deptService.findDeptsByIds(assessmentDeptIds);
    }

    @Override
    public void createTargetTasks(TargetTask targetTask) {
        if (targetTask.getReceiveDeptIds().isEmpty()) {
            throw new ServiceException("任务接收部门不能为空");
        }
        for (Long receiveDeptId: targetTask.getReceiveDeptIds()) {
            TargetTask opTargetTask = new TargetTask();
            BeanUtils.copyProperties(targetTask, opTargetTask);
            opTargetTask.setReceiveDeptId(receiveDeptId);
            createTargetTask(opTargetTask);
        }
    }

    @Override
    public TargetTask createTargetTask(TargetTask targetTask) {
        if (targetTask.getParentId() == 0) {
            targetTask.setLevel(TargetTaskLevel.top);
        } else {
            TargetTask parentTargetTask = getTargetTask(targetTask.getParentId());
            if (null == parentTargetTask) {
                throw new ServiceException("上级任务不存在");
            }

            if (parentTargetTask.getLevel() == TargetTaskLevel.first) {
                targetTask.setLevel(TargetTaskLevel.second);
            } else if (parentTargetTask.getLevel() == TargetTaskLevel.second) {
                targetTask.setLevel(TargetTaskLevel.third);
            } else if (parentTargetTask.getLevel() == TargetTaskLevel.top) {
                targetTask.setLevel(TargetTaskLevel.first);
            } else {
                throw new ServiceException("只能创建4级任务");
            }
        }
        User currentUser = getCurrentUser();
        if (null == targetTask.getStatus()) {
            targetTask.setStatus(AuditStatus.approving);
        }
        targetTask.setCreatedUserId(currentUser.getId());
        if (this.insert(targetTask)) {
            return targetTask;
        }

        return null;
    }

    @Override
    public TargetTask updateTargetTask(TargetTask targetTask) {
        if ((null == targetTask.getAttachmentId() || targetTask.getAttachmentId() == 0) && null != targetTask.getFileIds()) {
            Long attachmentId = attachmentService.create(targetTask.getFileIds(), FileTarget.task);
            targetTask.setAttachmentId(attachmentId);
        } else if (null != targetTask.getAttachmentId() && targetTask.getAttachmentId() != 0) {
            attachmentService.update(targetTask.getAttachmentId(), targetTask.getFileIds());
        }
        this.updateById(targetTask);

        return this.getTargetTask(targetTask.getId());
    }

    @Override
    public TargetTask passTargetTask(Long id) {
        TargetTask targetTask = this.selectById(id);
        if (null == targetTask) {
            throw new ServiceException("目标任务不存在");
        }

        targetTask.setStatus(AuditStatus.pass);

        if (this.updateById(targetTask)) {
            return targetTask;
        }

        return null;
    }

    @Override
    public TargetTask cancelPassTargetTask(Long id) {
        TargetTask targetTask = this.selectById(id);
        if (null == targetTask) {
            throw new ServiceException("目标任务不存在");
        }

        targetTask.setStatus(AuditStatus.approving);

        if (this.updateById(targetTask)) {
            return targetTask;
        }

        return null;
    }


    @Override
    public TargetTask getTargetTask(Long id) {
        TargetTask targetTask = this.selectById(id);

        if (null == targetTask) {
            return null;
        }
        targetTask.setTaskYear(taskYearMapper.selectById(targetTask.getYear()));

        if (null != targetTask.getAttachmentId() && targetTask.getAttachmentId() != 0) {
            targetTask.setFiles(attachmentService.findFildsByAttachmentId(targetTask.getAttachmentId()));
        }

        if (targetTask.getParentId() == 0) {

            targetTask.setTaskChain(targetTask.getTitle());
        } else {
            TargetTask parentTask = getTargetTask(targetTask.getParentId());
            targetTask.setTaskChain(parentTask.getTaskChain() + "/" + targetTask.getTitle());
        }

        return targetTask;
    }

    @Override
    public TaskYear getTaskYearByCode(String code) {
        TaskYear taskYear = new TaskYear();
        taskYear.setCode(code);
        return taskYearMapper.selectOne(taskYear);
    }

    @Override
    public TaskYear getTaskYear(Long yearId) {
        return taskYearMapper.selectById(yearId);
    }

    public YearTaskTree getYearTaskTree(Long yearId) {
        TaskYear taskYear = taskYearMapper.selectById(yearId);
        YearTaskTree yearTaskTree = new YearTaskTree();

        yearTaskTree.setId(taskYear.getId());
        yearTaskTree.setCode(taskYear.getCode());
        yearTaskTree.setTitle(taskYear.getTitle());
        yearTaskTree.setChildren(getTaskTree(yearId));

        return yearTaskTree;
    }

    @Override
    public List<TargetTask> findTargetTasksByParentIdAndYear(Long parentId, Long year) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("parent_id", parentId);
        wrapper.eq("year", year);
        wrapper.orderBy("seq", true);
        return this.selectList(wrapper);
    }

    @Override
    public List<TargetTask> findTargetTasksByDeptIdAndYear(Long deptId, Long year) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("receive_dept_id", deptId);
        wrapper.eq("year", year);
        return this.selectList(wrapper);
    }

    @Override
    public List<TargetTask> findTargetTasksByReceiveDeptIdAndOriginatedDeptIdAndYear(Long receiveDeptId, Long originatedDeptId, Long year) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("receive_dept_id", receiveDeptId);
        wrapper.eq("originated_dept_id", originatedDeptId);
        wrapper.eq("year", year);
        return this.selectList(wrapper);
    }

    @Override
    public List<TargetTaskTree> getTaskTree(Long yearId) {
        long rootId = 0;
        List<TargetTaskTree> rootTree = baseMapper.getTaskTreeByParentIdAndYear(rootId, yearId);
        List<TargetTask> tasks = findTasksByYear(yearId);
        List<Dept> depts = deptService.findAllDepts();
        Map<Long, Dept> deptMap = new HashMap<>();
        for (Dept dept : depts) {
            deptMap.put(dept.getId(), dept);
        }
        Map<Long, TargetTask> taskMap = new HashMap<>();
        Map<Long, List<TargetTaskTree>> taskTreeMap = new HashMap<>();
        for (TargetTask task : tasks) {
            taskMap.put(task.getId(), task);

            TargetTaskTree targetTaskTree = new TargetTaskTree();
            targetTaskTree.setId(task.getId());
            targetTaskTree.setTitle(task.getTitle());
            targetTaskTree.setOrigin(task.getOrigin());
            targetTaskTree.setOriginatedDeptId(task.getOriginatedDeptId());
            targetTaskTree.setYear(task.getYear());
            targetTaskTree.setStatus(task.getStatus());
            targetTaskTree.setReceiveDeptId(task.getReceiveDeptId());
            targetTaskTree.setLevel(task.getLevel());
            targetTaskTree.setParentId(task.getParentId());
            targetTaskTree.setLevelName(task.getLevelName());
            if (deptMap.containsKey(targetTaskTree.getReceiveDeptId())) {
                targetTaskTree.setReceiveDeptName(deptMap.get(targetTaskTree.getReceiveDeptId()).getName());
            } else {
                targetTaskTree.setReceiveDeptName("未选择部门");
            }

            List<TargetTaskTree> taskTrees = new ArrayList<>();
            if (taskTreeMap.containsKey(task.getParentId())) {
                taskTrees = taskTreeMap.get(task.getParentId());
            }
            taskTrees.add(targetTaskTree);
            taskTreeMap.put(task.getParentId(), taskTrees);
        }

        return this.setChildren(rootTree, yearId, taskMap, taskTreeMap);
    }

    private List<TargetTaskTree> setChildren(List<TargetTaskTree> tree, Long yearId, Map<Long, TargetTask> taskMap, Map<Long, List<TargetTaskTree>> taskTreeMap) {
        User currentUser = getCurrentUser();
        for (TargetTaskTree targetTaskTree : tree) {
            if (null != currentUser.getDeptId() && currentUser.getDeptId().equals(targetTaskTree.getReceiveDeptId())) {
                targetTaskTree.setMyDept(true);
            } else {
                targetTaskTree.setMyDept(false);
            }
            TargetTask parentTask =  taskMap.get(targetTaskTree.getParentId());
            if (null != parentTask && null != currentUser.getDeptId() && currentUser.getDeptId().equals(parentTask.getOriginatedDeptId())) {
                targetTaskTree.setMyAudit(true);
            } else {
                targetTaskTree.setMyAudit(false);
            }
            List<TargetTaskTree> subTree = taskTreeMap.get(targetTaskTree.getId());
            if (null != subTree) {
                targetTaskTree.setChildren(subTree);
                this.setChildren(subTree, yearId, taskMap, taskTreeMap);
            }
        }

        return tree;
    }

    @Override
    public List<TaskReportVo> getTaskReportByYearAndDeptId(Long year, Long deptId) {
        List<TargetTask> tasks = findTargetTasksByDeptIdAndYear(deptId, year);
        return getTaskReportByTasks(tasks, "work");
    }

    @Override
    public List<TaskReportVo> getTaskReportByReceiveDeptIdAndOriginatedDeptIdAndYear(Long receiveDeptId, Long originatedDeptId, Long year) {
        List<TargetTask> tasks = findTargetTasksByReceiveDeptIdAndOriginatedDeptIdAndYear(receiveDeptId, originatedDeptId, year);
        return getTaskReportByTasks(tasks, "standard");
    }

    @Override
    public List<TaskReportVo> getTaskReportByTasks(List<TargetTask> tasks, String type) {
        List<TaskReportVo> result = new ArrayList<>();
        for (TargetTask task : tasks) {
            if (type == "work") {
                List<TargetWork> works = targetWorkService.findByTaskId(task.getId());
                if (!works.isEmpty()) {
                    for (TargetWork work : works) {
                        TaskReportVo taskReportVo = getBaseTaskReportVo(task);
                        taskReportVo.setWork(work.getTitle());
                        taskReportVo.setWorkSeq(work.getSeq());
                        String responsibleUserName = "";
                        if (null != work.getResponsibleUser()) {
                            responsibleUserName = work.getResponsibleUser().getName();
                        }

                        if (null != work.getAssistUser()) {
                            responsibleUserName = responsibleUserName + " " + work.getAssistUser().getName();
                        }
                        taskReportVo.setResponsibleUser(responsibleUserName);
                        result.add(taskReportVo);
                    }
                } else {
                    TaskReportVo taskReportVo = getBaseTaskReportVo(task);
                    result.add(taskReportVo);
                }
            } else if (type == "standard") {
                TaskReportVo taskReportVo = getBaseTaskReportVo(task);
                result.add(taskReportVo);
            }
        }

        result = sortList(result, 1);

        return result;
    }

    private List<TaskReportVo> sortList(List<TaskReportVo> list, Integer step) {
        if (step > 4) {
            return list;
        }
        Map<Long, List<TaskReportVo>> result = new HashMap<>();
        Map<Integer, Long> sortMap = new HashMap<>();

        for (TaskReportVo taskReportVo : list) {
            int seq = 0;
            long title = 0;
            if (step == 1) {
                seq = taskReportVo.getTitleSeq();
                title = taskReportVo.getTitle();
            } else if (step == 2) {
                if (null == taskReportVo.getLevelASeq()) {
                    continue;
                }
                seq = taskReportVo.getLevelASeq();
                title = taskReportVo.getLevelA();
            } else if (step == 3) {
                if (null == taskReportVo.getLevelBSeq()) {
                    continue;
                }
                seq = taskReportVo.getLevelBSeq();
                title = taskReportVo.getLevelB();
            } else if (step == 4) {
                if (null == taskReportVo.getLevelCSeq()) {
                    continue;
                }
                seq = taskReportVo.getLevelCSeq();
                title = taskReportVo.getLevelC();
            }

            sortMap.put(seq, title);
            if (result.containsKey(title)) {
                List<TaskReportVo> tmpList = result.get(title);
                tmpList.add(taskReportVo);
                result.put(title, tmpList);
            } else {
                List<TaskReportVo> tmpList = new ArrayList<>();
                tmpList.add(taskReportVo);
                result.put(title, tmpList);
            }
        }

        List<TaskReportVo> sortReport = new ArrayList<>();

        List<List<TaskReportVo>> sortResult = new ArrayList<>();
        for (List<TaskReportVo> listReport : result.values()) {
            sortResult.add(sortList(listReport, ++step));
        }

        for (List<TaskReportVo> listReport1 : sortResult) {
            sortReport.addAll(listReport1);
        }
        return sortReport;
    }

    private TaskReportVo getBaseTaskReportVo(TargetTask task) {
        TaskReportVo taskReportVo = new TaskReportVo();
        long defalutTitle = task.getId();
        int defalutSeq = 0;
        if (task.getLevel() == TargetTaskLevel.top) {
            taskReportVo.setTitle(task.getId());
            taskReportVo.setTitleDesc(task.getTitle());
            taskReportVo.setTitleSeq(task.getSeq());

            taskReportVo.setLevelA(defalutTitle);
            taskReportVo.setLevelASeq(defalutSeq);

            taskReportVo.setLevelB(defalutTitle);
            taskReportVo.setLevelBSeq(defalutSeq);

            taskReportVo.setLevelC(defalutTitle);
            taskReportVo.setLevelCSeq(defalutSeq);
        } else if (task.getLevel() == TargetTaskLevel.first) {
            taskReportVo.setLevelC(defalutTitle);
            taskReportVo.setLevelCSeq(defalutSeq);

            taskReportVo.setLevelB(defalutTitle);
            taskReportVo.setLevelBSeq(defalutSeq);

            taskReportVo.setLevelA(task.getId());
            taskReportVo.setLevelADesc(task.getTitle());
            taskReportVo.setLevelASeq(task.getSeq());

            TargetTask topTask = getTargetTask(task.getParentId());
            taskReportVo.setTitle(topTask.getId());
            taskReportVo.setTitleDesc(topTask.getTitle());
            taskReportVo.setTitleSeq(topTask.getSeq());
        } else if (task.getLevel() == TargetTaskLevel.second) {
            taskReportVo.setLevelC(defalutTitle);
            taskReportVo.setLevelCSeq(defalutSeq);

            taskReportVo.setLevelB(task.getId());
            taskReportVo.setLevelBDesc(task.getTitle());
            taskReportVo.setLevelBSeq(task.getSeq());

            TargetTask firstTask = getTargetTask(task.getParentId());
            taskReportVo.setLevelA(firstTask.getId());
            taskReportVo.setLevelADesc(firstTask.getTitle());
            taskReportVo.setLevelASeq(firstTask.getSeq());

            TargetTask topTask = getTargetTask(firstTask.getParentId());
            taskReportVo.setTitle(topTask.getId());
            taskReportVo.setTitleDesc(topTask.getTitle());
            taskReportVo.setTitleSeq(topTask.getSeq());
        } else if (task.getLevel() == TargetTaskLevel.third) {
            taskReportVo.setLevelC(task.getId());
            taskReportVo.setLevelCDesc(task.getTitle());
            taskReportVo.setLevelCSeq(task.getSeq());

            TargetTask secondTask = getTargetTask(task.getParentId());
            taskReportVo.setLevelB(secondTask.getId());
            taskReportVo.setLevelBDesc(secondTask.getTitle());
            taskReportVo.setLevelBSeq(secondTask.getSeq());

            TargetTask firstTask = getTargetTask(secondTask.getParentId());
            taskReportVo.setLevelA(firstTask.getId());
            taskReportVo.setLevelADesc(firstTask.getTitle());
            taskReportVo.setLevelASeq(firstTask.getSeq());

            TargetTask topTask = getTargetTask(firstTask.getParentId());
            taskReportVo.setTitle(topTask.getId());
            taskReportVo.setTitleDesc(topTask.getTitle());
            taskReportVo.setTitleSeq(topTask.getSeq());
        }

        taskReportVo.setStandard(task.getAssessmentStandard());
        taskReportVo.setDeptId(task.getOriginatedDeptId());

        return taskReportVo;
    }

    @Override
    public List<TargetTask> findTasksByYear(Long year) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("year", year);
        wrapper.orderBy("seq", true);

        return this.selectList(wrapper);
    }
    @Override
    public void importTasks(List<TaskImporter> list) {
        if (list.isEmpty()) {
            return;
        }
        String deptName;
        User currentUser = getCurrentUser();
        String firstTaskName;
        String originatedDeptName;
        long paretnId = 0;
        TaskYear taskYear = new TaskYear();
        Dept originatedDept = new Dept();
        Dept recevicedDept = new Dept();
        Set<Long> assessmentIds = new HashSet<>();

        Map<String, Double> weightMap = new HashMap<>();
        Map<String, Double> taskWeightMap = new HashMap<>();

        String firstTaskDeptName = "";
        if (null != currentUser.getDept()) {
            firstTaskDeptName = currentUser.getDept().getName();
        }
        for (TaskImporter taskImporter : list) {
            if (null != taskImporter.getYear()) {
                if (taskImporter.getYear().length() != 4) {
                    throw new ServiceException("年度请填写当前年度的4位数字，便于一页纸报表的导入!");
                }
                taskYear.setTitle(taskImporter.getYear() + "年度");
                taskYear.setCode(taskImporter.getYear());
                taskYearMapper.insert(taskYear);
            }

            if (null != taskImporter.getFirstTaskDeptName()) {
                Dept checkDept = deptService.getDeptByName(taskImporter.getFirstTaskDeptName());
                if (null == checkDept) {
                    throw new ServiceException(taskImporter.getFirstTaskDeptName() + "不存在，请检查！");
                }
                firstTaskDeptName = taskImporter.getFirstTaskDeptName();
            }
            if (null != taskImporter.getOriginatedDeptName()) {
                Dept checkDept = deptService.getDeptByName(taskImporter.getOriginatedDeptName());
                if (null == checkDept) {
                    throw new ServiceException(taskImporter.getOriginatedDeptName() + "不存在，请检查！");
                }
            }

            if (null != taskImporter.getReceiveDeptName()) {
                Dept checkDept = deptService.getDeptByName(taskImporter.getReceiveDeptName());
                if (null == checkDept) {
                    throw new ServiceException(taskImporter.getReceiveDeptName() + "不存在，请检查！");
                }
            }
        }
        if (null == firstTaskDeptName || firstTaskDeptName.isEmpty() || firstTaskDeptName.equals("")) {
            throw new ServiceException("您没有部门，不能导入下达任务！");
        }
        Dept firstTaskDept = deptService.getDeptByName(firstTaskDeptName);
        if (null == firstTaskDept) {
            Dept newFirstTaskDept = new Dept();
            newFirstTaskDept.setType(DeptType.other);
            newFirstTaskDept.setName(firstTaskDeptName);
            newFirstTaskDept.setCode(String.valueOf(new Date().getTime()));
            firstTaskDept = deptService.createDept(newFirstTaskDept);
        }

        for (TaskImporter taskImporter : list) {
            if (null != taskImporter.getReceiveDeptName()) {
                deptName = taskImporter.getReceiveDeptName();
                recevicedDept = deptService.getDeptByName(deptName);
                if (null == recevicedDept) {
                    Dept newRecevicedDept = new Dept();
                    newRecevicedDept.setType(DeptType.other);
                    newRecevicedDept.setName(deptName);
                    newRecevicedDept.setCode(String.valueOf(new Date().getTime()));
                    recevicedDept = deptService.createDept(newRecevicedDept);
                }

            }

            if (null != taskImporter.getOriginatedDeptName()) {
                originatedDeptName = taskImporter.getOriginatedDeptName();
                originatedDept = deptService.getDeptByName(originatedDeptName);
                if (null == originatedDept) {
                    Dept dept = new Dept();
                    dept.setCode(String.valueOf(new Date().getTime()));
                    dept.setName(originatedDeptName);
                    dept.setType(DeptType.other);
                    originatedDept = deptService.createDept(dept);
                }
            }

            if (null != taskImporter.getFirstTask()) {
                firstTaskName = taskImporter.getFirstTask();
                TargetTask firstTask = new TargetTask();
                firstTask.setTitle(firstTaskName);
                firstTask.setParentId((long) 0);
                firstTask.setOrigin("A");
                firstTask.setOriginator(currentUser.getId());
                firstTask.setStatus(AuditStatus.pass);
                firstTask.setOriginatedDeptId(firstTaskDept.getId());
                firstTask.setYear(taskYear.getId());
                firstTask.setReceiveDeptId(originatedDept.getId());
                firstTask = createTargetTask(firstTask);
                paretnId = firstTask.getId();
            }

            TargetTask task = new TargetTask();
            task.setOriginator(currentUser.getId());
            task.setTitle(taskImporter.getSecondTask());
            task.setParentId(paretnId);
            task.setOrigin("B");
            task.setAssessmentElements(taskImporter.getAssessmentElements());
            task.setAssessmentStandard(taskImporter.getAssessmentStandard());
            task.setOriginatedDeptId(originatedDept.getId());
            task.setYear(taskYear.getId());
            task.setStatus(AuditStatus.pass);
            long recevicedDeptId;
            if (null == recevicedDept.getId()) {
                recevicedDeptId = 0;
            } else {
                recevicedDeptId = recevicedDept.getId();
            }
            task.setReceiveDeptId(recevicedDeptId);
            createTargetTask(task);
            if (null == taskImporter.getWeight()) {
                continue;
            }

            Assessment assessment = new Assessment();
            assessment.setYear(taskYear.getId());
            assessment.setAssessmentDeptId(originatedDept.getId());
            assessment.setAssessmentedDeptId(recevicedDept.getId());

            String weightKey = recevicedDept.getId().toString() + originatedDept.getId().toString();
            if (weightMap.containsKey(weightKey)) {
                double weight = weightMap.get(weightKey) + taskImporter.getWeight();
                weightMap.put(weightKey, weight);
            } else {
                weightMap.put(weightKey, taskImporter.getWeight());
            }

            taskWeightMap.put(task.getId().toString(), taskImporter.getWeight());

            try {
                assessment = assessmentService.createAssessment(assessment);
                assessmentIds.add(assessment.getId());
            } catch (ServiceException e) {
            }
        }

        for (Long assessmentId : assessmentIds) {
            List<AssessmentDetail> assessmentDetails = assessmentService.getAndInitAssessmentDetails(assessmentId);
            for (AssessmentDetail assessmentDetail : assessmentDetails) {
                if (taskWeightMap.containsKey(assessmentDetail.getFirstTaskId().toString())) {
                    String key = assessmentDetail.getAssessmentedDeptId().toString() + assessmentDetail.getAssessmentDeptId().toString();
                    if (weightMap.containsKey(key) && weightMap.get(key) > 0) {
                        Double weight = 1 / weightMap.get(key) * taskWeightMap.get(assessmentDetail.getFirstTaskId().toString()) * 100;
                        assessmentDetail.setWeight(weight.intValue());
                    }
                }
            }

            assessmentService.updateAssessmentDetails(assessmentDetails);
        }
    }

    @Override
    public List<TargetTask> findTaskSummary(Map<String, Object> conditions) {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        if (conditions.containsKey("deptId")) {
            wrapper.eq("receive_dept_id", conditions.get("deptId"));
        }
        if (conditions.containsKey("yearId")) {
            wrapper.eq("year", conditions.get("yearId"));
        }
        if (conditions.containsKey("keywords")) {
            wrapper.like("title", conditions.get("keywords").toString());
        }
        wrapper.orderBy("receive_dept_id", true);
        List<TargetTask> tasks = selectList(wrapper);
        for (TargetTask task : tasks) {
            task.setNextTaskNames(findChildNames(task));
            task.setWorks(targetWorkService.findByTaskId(task.getId()));
            task.setFileNames(getTaskFileNames(task));
        }
        return tasks;
    }

    private Set<String> getTaskFileNames(TargetTask task) {
        List<File> files = attachmentService.findFildsByAttachmentId(task.getAttachmentId());
        return BeanUtils.getFiled(files, "name", String.class);
    }

    private Set<String> findChildNames(TargetTask task) {
        Set<String> names = new HashSet<>();
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        wrapper.eq("parent_id", task.getId());
        List<TargetTask> list = selectList(wrapper);
        for (TargetTask child : list) {
            names.add(child.getTitle());
        }
        return names;
    }

    @Override
    public List<TargetTask> findAllTargetTask() {
        Wrapper<TargetTask> wrapper = new EntityWrapper<>();
        return this.selectList(wrapper);
    }

    @Override
    public void taskDrag(List<TaskDrag> taskDrags) {
        List<TargetTask> updateTargetTasks = new ArrayList<>();
        for (TaskDrag taskDrag: taskDrags) {
            TargetTask targetTask = new TargetTask();
            targetTask.setId(taskDrag.getId());
            targetTask.setSeq(taskDrag.getSeq());
            updateTargetTasks.add(targetTask);
        }

        this.updateBatchById(updateTargetTasks);
    }
    
    @Override
    public boolean batchCancelPassTargetTasks(Long id) {
        User currentUser = getCurrentUser();
        TargetTask targetTask = this.selectById(id);
        TargetTask parentTask = this.selectById(targetTask.getParentId());
        if (null != parentTask && null != currentUser.getDeptId()
                && currentUser.getDeptId().equals(parentTask.getOriginatedDeptId())) {
            targetTask.setStatus(AuditStatus.approving);
            this.updateById(targetTask);
        }
        List<TargetTask> childrenTasks = this.findTargetTasksByParentIdAndYear(targetTask.getId(),
                targetTask.getYear());
        if (null != childrenTasks) {
            for (TargetTask childrenTask : childrenTasks) {
                this.batchCancelPassTargetTasks(childrenTask.getId());
            }
        }
        return true;
    }

    @Override
    public boolean batchPassTargetTasks(Long id) {
        User currentUser = getCurrentUser();
        TargetTask targetTask = this.selectById(id);
        TargetTask parentTask = this.selectById(targetTask.getParentId());
        if (null != parentTask && null != currentUser.getDeptId()
                && currentUser.getDeptId().equals(parentTask.getOriginatedDeptId())) {
            targetTask.setStatus(AuditStatus.pass);
            this.updateById(targetTask);
        }
        List<TargetTask> childrenTasks = this.findTargetTasksByParentIdAndYear(targetTask.getId(),
                targetTask.getYear());
        if (null != childrenTasks) {
            for (TargetTask childrenTask : childrenTasks) {
                this.batchPassTargetTasks(childrenTask.getId());
            }
        }
        return true;
    }
}
